/*----------------------------------------------------------------------------
 *      RL-ARM - TCPnet
 *----------------------------------------------------------------------------
 *      Name:    STD_MODEM.C
 *      Purpose: Standard Modem Driver
 *      Rev.:    V4.12
 *----------------------------------------------------------------------------
 *      This code is part of the RealView Run-Time Library.
 *      Copyright (c) 2004-2010 KEIL - An ARM Company. All rights reserved.
 *---------------------------------------------------------------------------*/

#include "ATmodem.h"
#include "gtDev.h"

#define MODEM_NUM 4


#if ATMODEM_DEBUG
#define ATMODEM_PRINTF	gt_printf	//UART_SEND(0,(x),strlen(x))
#else
#define ATMODEM_PRINTF(...)

#endif


extern U64 ppp_buf[];


typedef const struct 
{
	U16	xPort : 3,
		xPin  : 4,
		xMode : 8,
		xSta  : 1;
	U8 xSpeed;
}t_modemmap;

extern t_modemmap MODEMMap[];
extern t_modemmap pppMap[];

#define MODEM_CFG(X) gt_gpio_cfg(MODEMMap[(X)].xPort,MODEMMap[(X)].xPin,MODEMMap[(X)].xMode,MODEMMap[(X)].xSta,MODEMMap[(X)].xSpeed)
#define MODEM_GET(X) gt_gpio_get(MODEMMap[(X)].xPort,MODEMMap[(X)].xPin)
#define MODEM_SET(X,V) gt_gpio_set(MODEMMap[(X)].xPort,MODEMMap[(X)].xPin,(V))

//init
void gt_modem_init(void)
{
	U8 i;
	for(i=0;i<MODEM_NUM;i++)
	  MODEM_CFG(i);
}
//pwr
void gt_modem_pwer(U8 x)
{
	MODEM_SET(0,(x));
}
//act
void gt_modem_act(U8 x)
{
	MODEM_SET(1,(x));
}
//dtr
void gt_modem_dtr(U8 x)
{
	MODEM_SET(2,(x));
}
//dcd
int gt_modem_dcd(void)
{
	return (MODEM_GET(3));
}


static int rst_step=0;
static int rst_cnt = 0;
extern int net_run_step;

extern unsigned char PPPSER_COM;
extern unsigned int PPPSER_BAUD;
extern unsigned char PPPSER_DATABIT;	  
extern unsigned char PPPSER_STOPBIT;
extern unsigned char PPPSER_PARITY;   
extern unsigned int PPPSER_RXBUF;
extern unsigned int PPPSER_TXBUF;
extern unsigned char DEBUG_PPPAT;
extern U32 unPPPbuf_size;


int gt_modem_step(unsigned int* nDelay)
{
	if(rst_cnt>0)
	{
		rst_cnt--;
		ATMODEM_PRINTF("\nMODEM...\n");
		return 1;
	}
	
 	net_run_step = rst_step;
	switch(rst_step)
	{
		case 0:
		{		
			ATMODEM_PRINTF("\nMODEM Restart...\n");
			gt_modem_init();
			gt_gpio_cfg(pppMap[0].xPort,pppMap[0].xPin,pppMap[0].xMode,pppMap[0].xSta,pppMap[0].xSpeed);//txd			
			gt_gpio_cfg(pppMap[1].xPort,pppMap[1].xPin,pppMap[1].xMode,pppMap[1].xSta,pppMap[1].xSpeed);//cts
			gt_gpio_cfg(pppMap[2].xPort,pppMap[2].xPin,pppMap[2].xMode,pppMap[2].xSta,pppMap[2].xSpeed);//rts
			*nDelay = 5;
			break; 
		}
		case 1:
		{
			gt_gpio_cfg(pppMap[3].xPort,pppMap[3].xPin,pppMap[3].xMode,pppMap[3].xSta,pppMap[3].xSpeed);//rst
			gt_gpio_cfg(pppMap[0].xPort,pppMap[0].xPin,0x18,pppMap[0].xSta,pppMap[0].xSpeed);//gt_modem_cfgtx(0);	// 
			gt_modem_act(1);		//0
			gt_modem_pwer(1);
			*nDelay = 2;			
			break;
		}
		case 2:
		{
			gt_modem_act(0);
			*nDelay = 1;
			break;
		}
		case 3:
		{
			gt_modem_dtr(1);
			*nDelay = 1;
			break;
		}		
		case 4:
		{
 			gt_gpio_set(pppMap[3].xPort,pppMap[3].xPin,1);//rst
			*nDelay = 1;
			break;
		}				
		
		case 5:
		{
			gt_modem_dtr(0);
			*nDelay = 1;
			break;
		}	
		case 6:
		{
			gt_modem_dtr(1);
			*nDelay = 5;
			break;
		}			
		case 7:
		{
			gt_modem_act(1);
//			gt_modem_dtr(0);
			*nDelay = 10;
			rst_step=0;
			rst_cnt=0;
			gt_uart_open(PPPSER_COM,PPPSER_BAUD,PPPSER_DATABIT,PPPSER_PARITY,PPPSER_STOPBIT,PPPSER_RXBUF,PPPSER_TXBUF); 
			return 1;		
		}
		default:
			rst_step=0;
			break;
	}
	rst_step++;
	return 0;
}


int gt_modem_online(void)
{
	if(gt_modem_dcd()==0)return 1;
	return 0;
}


int gt_ppp_open(unsigned char** buf,unsigned int* size)
{
	*buf = (unsigned char*)ppp_buf;
//	*size = PPP_BUF_SIZE;
	*size = unPPPbuf_size;
	gt_uart_open(PPPSER_COM,PPPSER_BAUD,PPPSER_DATABIT,PPPSER_PARITY,PPPSER_STOPBIT,PPPSER_RXBUF,PPPSER_TXBUF);
	return 1;
}

int gt_ppp_send(const void* pBuf,int size)
{
	ATMODEM_PRINTF("%s",pBuf);
	return gt_uart_send(PPPSER_COM,pBuf,size);
}


int gt_ppp_recv(void* pBuf,int size)
{
	int i;
	int ret;
 	ret = gt_uart_rev(PPPSER_COM,pBuf,size,50,10);
	for(i=0;i<ret;i++)
		ATMODEM_PRINTF("%c",*((U8*)pBuf+i));
	return ret;
}




